﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using System.Reflection;
using Toolkit.Web.Validation;
using System.ComponentModel.DataAnnotations;

namespace Toolkit.Web.Mvc.Validation
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class PhoneNumberAttribute : ValidationAttribute
    {
        public PhoneNumberAttribute(string isoCountryCode2)
        {
            IsoCountryCode2 = isoCountryCode2;
        }

        public string IsoCountryCode2
        {
            get;
            set;
        }

        public bool AllowErrorMessageOverride
        {
            get;
            set;
        }

        protected string ErrorMessageOverride
        {
            get;
            private set;
        }

        public override bool IsValid(object value)
        {
            PhoneNumberValidator phoneNumberValidator = new PhoneNumberValidator(value as string, IsoCountryCode2);
            string result = phoneNumberValidator.Validate();

            if (result != null && !string.IsNullOrEmpty(result) && AllowErrorMessageOverride)
            {
                // Set error message if a default message has not been given.
                ErrorMessageOverride = result;
            }

            return (result == null);
        }

        public override string FormatErrorMessage(string name)
        {
            if (AllowErrorMessageOverride && !string.IsNullOrEmpty(ErrorMessageOverride))
            {
                return ErrorMessageOverride;
            }
            return base.FormatErrorMessage(name);
        }
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class PhoneNumberDependentAttribute : ValidationAttribute, IDependentFieldModelValidationAttribute
    {
        public PhoneNumberDependentAttribute(string dependentPropertyName)
        {
            DependentPropertyName = dependentPropertyName;
        }

        public string DependentPropertyName
        {
            get;
            set;
        }

        public bool AllowErrorMessageOverride
        {
            get;
            set;
        }

        protected string ErrorMessageOverride
        {
            get;
            private set;
        }

        public override bool IsValid(object value)
        {
            // Work done in other IsValid method.
            return true;
        }

        public override string FormatErrorMessage(string name)
        {
            if (AllowErrorMessageOverride && !string.IsNullOrEmpty(ErrorMessageOverride))
            {
                return ErrorMessageOverride;
            }
            return base.FormatErrorMessage(name);
        }

        public bool IsValid(ControllerContext controllerContext, object model, ModelMetadata modelMetadata)
        {
            string result = null;
            PropertyInfo dependentPropertyInfo = model.GetType().GetProperty(DependentPropertyName);

            if (dependentPropertyInfo == null)
            {
                throw new InvalidOperationException("Unknown property: " + DependentPropertyName);
            }

            string dependentPropertyValue = dependentPropertyInfo.GetGetMethod().Invoke(model, null) as string;

            if (!string.IsNullOrEmpty(dependentPropertyValue))
            {
                PhoneNumberValidator phoneNumberValidator = new PhoneNumberValidator(modelMetadata.Model as string, dependentPropertyValue);
                result = phoneNumberValidator.Validate();

                if (result != null && !string.IsNullOrEmpty(result) && AllowErrorMessageOverride)
                {
                    ErrorMessageOverride = result;
                }
            }

            return (result == null);
        }
    }
}
